summaryrefslogblamecommitdiffstats
path: root/main.hpp
blob: e099986937f914bc0fb8874866e3b84f21e31d2e (plain) (tree)
1
2
3
4
5
6
7
8
9

                 
                 



                   

                            







































                                                                                                   

                                                                                               



                                                                                             
















                                                                                             
                                                                                                       
                                                              

                                    

                            


                                                                                        
                       
                                                   







                                                                                             
                                                                                       







                                                                                              
                       
                                          
                                                   
                                                 

                                                             



                                                                        


                                                                     



                                                                                                   

                                                    






                                                                                                  





                                           








                                                  




                                                                                                 



                                                                                     

                                                                 
                                                                 
                                                  
                                 





                                         
                                                                                     
                                                                   


                                                                        
                                            
          
                                                
 
#include <vector>
#include <queue>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <regex>
namespace ov {
	using namespace std;
	struct NotImplemented : public exception {
	const char * what () const throw () {
		return "Not implemented.";
	}
	} NotImplemented;
	struct NotAvailable : public exception {
		const char * what () const throw () {
			return "I/O is currently not available. You can try again.";
		}
	} NotAvailable;
	struct BufferingRequired : public exception {
		const char * what () const throw () {
			return "I/O buffering must be enabled for this function, but it's not.";
		}
	} BufferingRequired;
	struct NotAligned : public exception {
		const char * what () const throw () {
			return "Byte count can't be deserialized without remainder.";
		}
	} NotAligned;
	struct AssemblerFatal : public exception {
		const char * what () const throw () {
			return "Fatal error in assembler.";
		}
	} AssemblerFatal;
	struct SyntaxError : AssemblerFatal {
		const char * what () const throw () {
			return "Fatal syntax error in assembler.";
		}
	} SyntaxError;
	struct EndlessArgument : public SyntaxError {
		const char * what () const throw () {
			return "Some builtin preprocessor command does not have enough arguments.";
		}
	} EndlessArgument;
	struct EndlessBlock : public SyntaxError {
		const char * what () const throw () {
			return "Some builtin preprocessor block %* is not terminated with %end*.";
		}
	} EndlessBlock;
	enum opts { // opts are pas-1 bits aftr last ram ptr (2**ras)-1 and can be w/r from prg
		DEFAULT,
		BUFOUT,		// output from program in VM is always possible and no blocks
		BUFIN,		// input to program in VM is always possible and no blocks
		BUFINCLR,	// clears whatever is in the input buffer
		BUFOUTCLR,	// clears whatever is in the output buffer
		OPTSLEN
	}; // read those last bits with the COPY instruction with source/dest on last pointer
	enum iobits {
		INA,	// input available, clear when read
		IN,	// input bit
		OUTA,	// output available, set when have output, cleared by VM when wrote
		OUT,	// output bit
		IOLEN
	};
	enum instrs {
		COPY,
		NAND
	};
	struct instr {			// deserializirana inštrukcija
		unsigned int s = 0;	// source
		unsigned int d = 0;	// destination
		bool i = 0;		// instruction
		bool p = 0;		// enobitni padding, lahko za metainštrukcije, pri COPY je že
	};	// privzeto inicializiran na NOOP inštrukcijo
	struct def {
		vector<string> args;
		string body;
	};
	class Ov;									
	template<typename value_type, typename index_type> class Ram {
		private:
		public:
			vector<value_type> storage;
			Ov * ov;
			value_type peek (index_type);
			void poke(index_type, value_type);
			Ram (Ov *);
	};
	/* v Program (memory) bi lahko uporabili metainštrukcije (tisti padding bit) v
	 * vsaki inštrukciji in v metainštrukcijah reprezentirali assembly org (lokacijo).
	 * s tem bi lahko imeli npr. 128 biten program counter in s tem zelo preproste jumpe,
	 * ne bi pa bilo treba narediti 2^128 vektorja in posledično binarne datoteke.
	 * Tak način bi bilo verjetno težko implementirati na dejanski strojni opremi,
	 * tukaj pa bi v enem passu čez cel deserializan program memory zaznali te org
	 * metainštrukcije in naredili neko tabelo oziroma prevajalnik program counterja
	 * v lokacijo v vektorju. problem je, da bi se morala prevajalska tabela vsakič znova
	 * regenerirati, ko spreminjamo program memory.
	 * */
	template<typename value_type, typename index_type> class Program {
		private:
		public:
			index_type hiaddr;
			vector<value_type> storage;
			const struct instr empty;
			Ov * ov;
			value_type & peek (index_type addr) {
				if (addr > hiaddr) {
					hiaddr = addr;
					storage.resize(hiaddr+1, empty);
				}
				return storage[addr];
			}
			void poke (index_type addr, value_type val) {
				if (addr > hiaddr) {
					hiaddr = addr;
					storage.resize(hiaddr+1, empty /* avoid leaking memory */);
				}
				storage[addr] = val;
			}
			index_type length () {
				return hiaddr+1;
			}
			Program (Ov * ov) : ov(ov) {
				hiaddr = 0;
				storage.push_back(empty); // we don't want to leak memory contents
			}
	};
	class Ov {
		private:
		public:
			queue<bool> inbuf;
			queue<bool> outbuf;
			unsigned int ras (void) {
				return (is*8-2)/2;
			}
			unsigned int rs (void) {
				return 1 << ras();
			}
			unsigned int ps (void) {
				return 1 << pas;
			}
			unsigned short int is;
			unsigned short int pas;
			bool io[IOLEN];
			bool opts[OPTSLEN];
			unsigned int pc = 0; /* where the program starts --- at zero or where? */
			Ram<bool, unsigned int> r{this};
			Program<struct instr, unsigned int> p{this};
			Ov (unsigned short int is = 2, unsigned short int pas = 16) :
	       			is(is), pas(pas) { // TODO: check
				for (int i = 0; i < OPTSLEN; i++)
					opts[i] = 0;
				for (int i = 0; i < IOLEN; i++) {
					io[i] = 0;
				}
			}
			void step (void);
			bool out (void);
			char outc (void);
			void in (bool);
			void inc (char);
			struct instr deserialize (const char [sizeof(struct instr)]);
			void deserialize (istream &, unsigned int);
			void deserialize (string, unsigned int);
			string serialize (struct instr *, unsigned int);
			string serialize (struct instr);
			void pd (ostream &);
	};
	vector<struct instr> assembler (string);
}